
function normalizeData(value) {
  if (value === 'true') {
    return true
  }

  if (value === 'false') {
    return false
  }

  if (value === Number(value).toString()) {
    return Number(value)
  }

  if (value === '' || value === 'null') {
    return null
  }

  if (typeof value !== 'string') {
    return value
  }

  try {
    return JSON.parse(decodeURIComponent(value))
  } catch {
    return value
  }
}

function normalizeDataKey(key) {
  return key.replace(/[A-Z]/g, (chr) => `-${chr.toLowerCase()}`)
}

export default function createManipulator({ DATA_PREFIX, DATA_PREFIX_BASE }) {
  const Manipulator = {
    setDataAttribute(element, key, value) {
      element.setAttribute(`data-${DATA_PREFIX}${normalizeDataKey(key)}`, value)
    },

    removeDataAttribute(element, key) {
      element.removeAttribute(`data-${DATA_PREFIX}${normalizeDataKey(key)}`)
    },

    getDataAttributes(element) {
      if (!element) {
        return {}
      }

      const attributes = {}

      const configKeys = Object.keys(element.dataset).filter(
        (key) => key.startsWith(DATA_PREFIX_BASE) && !key.startsWith(`${DATA_PREFIX_BASE}Config`),
      )

      for (const key of configKeys) {
        let pureKey = key
          // .replace(/^bs/, '')
          .slice(DATA_PREFIX_BASE.length)
        pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1)
        attributes[pureKey] = normalizeData(element.dataset[key])
      }

      return attributes
    },

    getDataAttribute(element, key) {
      return normalizeData(
        element.getAttribute(`data-${DATA_PREFIX}${normalizeDataKey(key)}`),
      )
    },
  }

  return Manipulator
}
